# coding:utf-8
import sys
from typing import Union

from PyQt6.QtCore import QUrl, Qt, QSizeF, QEvent, QTimer
from PyQt6.QtGui import QKeyEvent, QPainter, QWheelEvent
from PyQt6.QtMultimedia import QMediaPlayer
from PyQt6.QtMultimediaWidgets import QGraphicsVideoItem
from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from qfluentwidgets import FluentIcon as FIF, ImageLabel, MessageDialog

from common import SingleIcon
from .media_player_bar import SimpleMediaPlayBar
from .progress_widget import ProgressWidget


class VideoGraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.videoGraphicsScene = QGraphicsScene(self)
        self.videoGraphicsItem = QGraphicsVideoItem()
        self.playerBar = SimpleMediaPlayBar(self)
        self.timer = QTimer(self)
        self.backgroundLabel = ImageLabel(SingleIcon.VIDEO_BG.path(), self)
        self.progressWidget = ProgressWidget(self)

        self.__initWidgets()
        self.__connectSignals()

    def __initWidgets(self):
        self.setMinimumSize(600, 600)
        self.videoGraphicsScene.addItem(self.videoGraphicsItem)
        self.setScene(self.videoGraphicsScene)
        # 设置初始尺寸
        self.videoGraphicsItem.setSize(QSizeF(self.size()))
        # 新增视图缩放设置
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.LosslessImageRendering)
        self.setViewportUpdateMode(QGraphicsView.ViewportUpdateMode.FullViewportUpdate)
        self.setStyleSheet('VideoGraphicsView {background-color: transparent; border: none}')
        self.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.timer.setInterval(3000)
        self.timer.timeout.connect(self.playerBar.hide)
        self.timer.start()

        self.installEventFilter(self)
        self.playerBar.installEventFilter(self)
        self.setMouseTracking(True)

        self.backgroundLabel.setFixedSize(self.size())
        self.backgroundLabel.setScaledContents(True)
        self.backgroundLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.backgroundLabel.lower()

        self.progressWidget.raise_()
        self.progressWidget.setVisible(False)

    def resizeEvent(self, event):
        self.videoGraphicsItem.setSize(QSizeF(self.size()))
        self.setSceneRect(0, 0, self.width(), self.height())
        # 控制条定位
        self.playerBar.move(0, self.height() - self.playerBar.height())
        self.playerBar.resize(self.width(), self.playerBar.height())
        self.playerBar.raise_()
        self.backgroundLabel.setFixedSize(self.size())
        self.backgroundLabel.lower()
        # 进度条定位
        self.progressWidget.move((self.width() - self.progressWidget.width()) // 2,
                                 (self.height() - self.progressWidget.height()) // 2)
        super().resizeEvent(event)

    def __connectSignals(self):
        self.playerBar.setVideoOutput(self.videoGraphicsItem)
        self.playerBar.fullScreenButton.clicked.connect(self.toggleFullScreen)

        self.playerBar.player.mediaStatusChanged.connect(self.__handleMediaStatusChanged)
        self.playerBar.player.bufferProgressChanged.connect(self.__handleBufferStatusChanged)
        self.playerBar.player.errorOccurred.connect(self.__handleErrorChanged)

    def __handleMediaStatusChanged(self, status: QMediaPlayer.MediaStatus):
        if status == QMediaPlayer.MediaStatus.LoadingMedia:
            self.progressWidget.setVisible(True)
            self.backgroundLabel.setVisible(False)
        elif status == QMediaPlayer.MediaStatus.LoadedMedia:
            self.progressWidget.setVisible(False)
            self.playerBar.play()
        elif status == QMediaPlayer.MediaStatus.InvalidMedia:
            self.progressWidget.setVisible(False)
            self.backgroundLabel.setVisible(True)
            self.playerBar.stop()
        elif status == QMediaPlayer.MediaStatus.EndOfMedia:
            self.backgroundLabel.setVisible(True)
            self.playerBar.stop()
        elif status == QMediaPlayer.MediaStatus.StalledMedia:
            self.progressWidget.setVisible(True)
        elif status == QMediaPlayer.MediaStatus.BufferingMedia:
            self.progressWidget.setVisible(True)
        elif status == QMediaPlayer.MediaStatus.BufferedMedia:
            self.progressWidget.setVisible(False)

    def __handleBufferStatusChanged(self, progress: int):
        self.progressWidget.setValue(progress)

    def __handleErrorChanged(self, error: QMediaPlayer.Error):
        """ 播放错误槽函数 """
        if error == QMediaPlayer.Error.NoError:
            return

        messageMap = {
            QMediaPlayer.Error.ResourceError: "无法解析媒体资源。",
            QMediaPlayer.Error.FormatError: "不支持媒体资源的格式。",
            QMediaPlayer.Error.NetworkError: "网络错误，无法播放媒体资源。",
            QMediaPlayer.Error.AccessDeniedError: "没有播放媒体资源的适当权限。"
        }
        w = MessageDialog(
            '视频发生错误',
            messageMap[error],
            self
        )
        w.yesButton.hide()
        w.cancelButton.setText(self.tr('关闭'))
        w.exec()

    def toggleFullScreen(self):
        if self.isFullScreen():
            self.setFullScreen(False)
        else:
            self.setFullScreen(True)

    def setSource(self, url: Union[str, QUrl]):
        self.playerBar.setSource(url)

    def setFullScreen(self, fullScreen: bool):
        if fullScreen:
            self.setWindowState(self.windowState() | Qt.WindowState.WindowFullScreen)
            self.setWindowFlags(self.windowFlags() | Qt.WindowType.Window)
            self.playerBar.fullScreenButton.setIcon(FIF.BACK_TO_WINDOW)
            self.playerBar.fullScreenButton.setToolTip(self.tr('退出全屏'))
        else:
            self.playerBar.fullScreenButton.setIcon(FIF.FULL_SCREEN)
            self.setWindowFlags(self.windowFlags() | Qt.WindowType.SubWindow)
            self.setWindowState(self.windowState() & ~Qt.WindowState.WindowFullScreen)
            self.playerBar.fullScreenButton.setToolTip(self.tr('全屏'))

    def play(self):
        self.playerBar.play()

    def pause(self):
        self.playerBar.pause()

    def stop(self):
        self.playerBar.stop()

    def keyPressEvent(self, a0: QKeyEvent):
        if a0.key() == Qt.Key.Key_Escape:
            if self.isFullScreen():
                self.setFullScreen(False)
        elif a0.key() == Qt.Key.Key_F11:
            self.toggleFullScreen()
        elif a0.key() == Qt.Key.Key_Space:
            self.playerBar.togglePlayState()
        elif a0.key() == Qt.Key.Key_Left:
            self.playerBar.player.setPosition(self.playerBar.player.position() - 1000)
        elif a0.key() == Qt.Key.Key_Right:
            self.playerBar.player.setPosition(self.playerBar.player.position() + 1000)

    def wheelEvent(self, a0: QWheelEvent) -> None:
        pass

    def leaveEvent(self, a0: QEvent) -> None:
        self.playerBar.hide()

    def enterEvent(self, a0: QEvent) -> None:
        self.activateWindow()

    def mouseMoveEvent(self, event):
        self.playerBar.show()
        self.timer.stop()
        self.timer.start()
        super().mouseMoveEvent(event)

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.playerBar.hide()
            self.setCursor(Qt.CursorShape.ClosedHandCursor)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = VideoGraphicsView()
    widget.resize(800, 600)
    # url = QUrl.fromLocalFile(r"G:\手机\视频与图片\video_20210211_185653.mp41")
    # url = 'https://v16m-default.akamaized.net/913143e916ea4b8547007266e4e8780e/67e504b1/video/tos/alisg/tos-alisg-ve-0051c001-sg/oIgFcDBcQbNQd3Du8f6XGI3xnsXfNDYPojEgAB/?a=2011&bti=MzhALjBg&ch=0&cr=0&dr=0&net=5&cd=0%7C0%7C0%7C0&br=1126&bt=563&cs=0&ds=3&ft=XE5bCqq3mbuPD12Y~59J3wU1NmxdEeF~O5&mime_type=video_mp4&qs=0&rc=Nzk1PDpoaDppNzc6ZTs3aUBpM2o1c3c5cnVxeDMzODYzNEAxM2AuLV8yNjExXjViNTQvYSM0cGsyMmRrb2VgLS1kMC1zcw%3D%3D&vvpl=1&l=20250327013252A60CEC4869EA8FAE16CB&btag=e000a8000'
    # widget.setSource(url)
    widget.show()
    sys.exit(app.exec())
